use arboard::Clipboard;
use winit::{
    event::{Event, WindowEvent},
    event_loop::{ControlFlow, EventLoop},
};
use rusqlite::{params, Connection, OptionalExtension};

fn get_clipboard_content() -> Option<String> {
    let mut clipboard = Clipboard::new().ok()?;
    clipboard.get_text().ok()
}

fn init_db(conn: &Connection) {
    conn.execute(
        "CREATE TABLE IF NOT EXISTS clipboard_data (
            id INTEGER PRIMARY KEY,
            content TEXT UNIQUE,
            count INTEGER DEFAULT 1,
            is_favorite INTEGER DEFAULT 0,
            create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
            update_time DATETIME DEFAULT CURRENT_TIMESTAMP
        )",
        [],
    ).unwrap();
}

fn insert_or_update(conn: &Connection, content: &str) {
    let mut stmt = conn.prepare("SELECT count FROM clipboard_data WHERE content = ?1").unwrap();
    let exists: Option<i32> = stmt.query_row([content], |row| row.get(0)).optional().unwrap();
    if let Some(count) = exists {
        conn.execute(
            "UPDATE clipboard_data SET count = ?1, update_time = CURRENT_TIMESTAMP WHERE content = ?2",
            params![count + 1, content],
        ).unwrap();
    } else {
        conn.execute(
            "INSERT INTO clipboard_data (content) VALUES (?1)",
            params![content],
        ).unwrap();
    }
}

fn main() {
    unsafe { std::env::set_var("RUST_BACKTRACE", "full"); }
    let conn = Connection::open("/Users/zadine/self/app/pasteboard_tool/clipboard.db").unwrap();
    init_db(&conn);

    let event_loop = EventLoop::new();

    let mut last_clipboard_content: Option<String> = None;

    event_loop.run(move |event, _, control_flow| {
        *control_flow = ControlFlow::Wait;

        match event {
            Event::WindowEvent {
                event: WindowEvent::CloseRequested,
                ..
            } => *control_flow = ControlFlow::Exit,
            Event::MainEventsCleared => {
                if let Some(content) = get_clipboard_content() {
                    if last_clipboard_content.as_deref() != Some(&content) {
                        insert_or_update(&conn, &content);
                        println!("=======================================>");
                        println!("{content}");
                        last_clipboard_content = Some(content);
                    }
                }
            }
            _ => (),
        }
    });
}

// nohup /Users/zadine/self/app/pasteboard_tool/pasteboard_tool &> /Users/zadine/self/app/pasteboard_tool/pasteboard_tool.log &